﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BaseHangul;

namespace BaseHangulDotNetTester
{
    class Program
    {
        static void Main(string[] args)
        {
            TestEncode();
            TestDecode();
        }

        private static string BinToStr(byte[] binData)
        {
            return string.Concat(binData.Select(b => b.ToString("X2")).ToArray());
        }

        // Test Data from BaseHangul for Ruby(https://github.com/yous/basehangul) by yous

        static void TestEncode()
        {
            var _TestEncodeFun = new Func<byte[], string, bool>(
                (data, expected) =>
                {
                    Console.WriteLine(" * Try to encode [{0}] ..", BinToStr(data));
                    string encoded = BaseHangulEncoding.Encode(data);
                    if (encoded == expected)
                    {
                        Console.WriteLine(" (OK) Result is \"{0}\"", encoded);
                        return true;
                    }
                    else
                    {
                        Console.WriteLine(" (FAILED) Result is \"{0}\", but \"{1}\" was expected", encoded, expected);
                        return false;
                    }
                });

            Console.WriteLine("---- TEST for BaseHangul Encoding ----");

            Console.WriteLine("returns empty string with empty binary");
            _TestEncodeFun(Encoding.ASCII.GetBytes(""), "");
            Console.WriteLine();

            Console.WriteLine("when the length is multiple of 5");
            _TestEncodeFun(Encoding.ASCII.GetBytes("This is an encoded string"), "넥라똔먈늴멥갯놓궂뗐밸뮤뉴뗐뀄굡덜멂똑뚤");
            _TestEncodeFun(Encoding.ASCII.GetBytes("123ab"), "꺽먹꼍녜");
            _TestEncodeFun(Encoding.ASCII.GetBytes("123d\0"), "꺽먹꼐가");
            Console.WriteLine();

            Console.WriteLine("when the remainder is 1, 2, 3 when the length is divided by 5");
            _TestEncodeFun(Encoding.ASCII.GetBytes("1"), "꺽흐흐흐");
            _TestEncodeFun(Encoding.ASCII.GetBytes("12"), "꺽먈흐흐");
            _TestEncodeFun(Encoding.ASCII.GetBytes("123"), "꺽먹꺄흐");
            Console.WriteLine();

            Console.WriteLine("when the remainder is 4 when the length is divided by 5");
            _TestEncodeFun(Encoding.ASCII.GetBytes("123d"), "꺽먹꼐빎");
            _TestEncodeFun(Encoding.ASCII.GetBytes("123e"), "꺽먹꼐빔");
            _TestEncodeFun(Encoding.ASCII.GetBytes("123f"), "꺽먹꼐빕");
            _TestEncodeFun(Encoding.ASCII.GetBytes("123g"), "꺽먹꼐빗");
            Console.WriteLine();

            Console.WriteLine("---- END of Encoding Test ----");
            Console.WriteLine();
            Console.WriteLine();
        }

        static void TestDecode()
        {
            var _TestDecodeFun = new Func<string, byte[], bool>(
                (encodedStr, expected) =>
                {
                    Console.WriteLine(" * Try to decode \"{0}\" ..", encodedStr);
                    byte[] decoded = BaseHangulEncoding.Decode(encodedStr);
                    string decodedStr = BinToStr(decoded);
                    string expectedStr = BinToStr(expected);
                    if (decodedStr == expectedStr)
                    {
                        Console.WriteLine(" (OK) Result is [{0}]", decodedStr);
                        return true;
                    }
                    else
                    {
                        Console.WriteLine(" (FAILED) Result is [{0}], but [{1}] was expected", decodedStr, expectedStr);
                        return false;
                    }
                });

            Console.WriteLine("---- TEST for BaseHangul Deconding ----");

            Console.WriteLine("returns empty binary with empty string");
            _TestDecodeFun("", Encoding.ASCII.GetBytes(""));
            Console.WriteLine();

            Console.WriteLine("when there is no padding characters");
            _TestDecodeFun("넥라똔먈늴멥갯놓궂뗐밸뮤뉴뗐뀄굡덜멂똑뚤", Encoding.ASCII.GetBytes("This is an encoded string"));
            _TestDecodeFun("꺽먹꼍녜", Encoding.ASCII.GetBytes("123ab"));
            _TestDecodeFun("꺽먹꼐가", Encoding.ASCII.GetBytes("123d\0"));
            Console.WriteLine();

            Console.WriteLine("when there are padding characters");
            _TestDecodeFun("꺽흐흐흐", Encoding.ASCII.GetBytes("1"));
            _TestDecodeFun("꺽먈흐흐", Encoding.ASCII.GetBytes("12"));
            _TestDecodeFun("꺽먹꺄흐", Encoding.ASCII.GetBytes("123"));
            Console.WriteLine();

            Console.WriteLine("when there are special characters");
            _TestDecodeFun("꺽먹꼐빎", Encoding.ASCII.GetBytes("123d"));
            _TestDecodeFun("꺽먹꼐빔", Encoding.ASCII.GetBytes("123e"));
            _TestDecodeFun("꺽먹꼐빕", Encoding.ASCII.GetBytes("123f"));
            _TestDecodeFun("꺽먹꼐빗", Encoding.ASCII.GetBytes("123g"));
            Console.WriteLine();

            Console.WriteLine("---- END of Decoding Test ----");
            Console.WriteLine();
            Console.WriteLine();
        }
    }
}
